#ifndef SRP_H
#define SRP_H

#ifdef __cplusplus
extern "C" {
#endif

#define SRP_SHA_DIGEST_LENGTH 20

void srp_init( const char * random_seed, int seed_len );
void srp_fini();

int srp_is_initialized();

struct SRPVerifier;
struct SRPUser;

/* Out: bytes_s, len_s, bytes_v, len_v
 * 
 * The caller is responsible for freeing the memory allocated for bytes_s and bytes_v
 */
void srp_gen_sv( const char * username,
                 const unsigned char * password, int len_password,
                 const unsigned char ** bytes_s, int * len_s, 
                 const unsigned char ** bytes_v, int * len_v );


/* Out: bytes_B, len_B.
 * 
 * On failure, bytes_B will be set to NULL and len_B will be set to 0
 */
struct SRPVerifier *  srp_verifier_new( const char * username,
                                        const unsigned char * bytes_s, int len_s, 
                                        const unsigned char * bytes_v, int len_v,
                                        const unsigned char * bytes_A, int len_A,
                                        const unsigned char ** bytes_B, int * len_B);


void                  srp_verifier_delete( struct SRPVerifier * ver );


int                   srp_verifier_is_authenticated( struct SRPVerifier * ver );


/* Key length is SRP_SHA_DIGEST_LENGTH */
const unsigned char * srp_verifier_get_session_key( struct SRPVerifier * ver );


/* user_M must be exactly SRP_SHA_DIGEST_LENGTH bytes in size */
void                  srp_verifier_verify_session( struct SRPVerifier * ver,
                                                   const unsigned char * user_M, 
                                                   const unsigned char ** bytes_HAMK );

/*******************************************************************************/

struct SRPUser *      srp_user_new( const char * username, 
                                    const unsigned char * bytes_password, int len_password );
                                    
void                  srp_user_delete( struct SRPUser * usr );

int                   srp_user_is_authenticated( struct SRPUser * usr);

/* Key length is SRP_SHA_DIGEST_LENGTH */
const unsigned char * srp_user_get_session_key( struct SRPUser * usr );

/* Output: username, bytes_A, len_A */
void                  srp_user_start_authentication( struct SRPUser * usr, const char ** username, 
                                                     const unsigned char ** bytes_A, int * len_A );

/* Output: bytes_M. Buffer length is SRP_SHA_DIGEST_LENGTH */
void                  srp_user_process_challenge( struct SRPUser * usr, 
                                                  const unsigned char * bytes_s, int len_s, 
                                                  const unsigned char * bytes_B, int len_B,
                                                  const unsigned char ** bytes_M );
                                                  
/* bytes_HAMK must be exactly SRP_SHA_DIGEST_LENGTH bytes in size */
void                  srp_user_verify_session( struct SRPUser * usr, const unsigned char * bytes_HAMK );
    
#ifdef __cplusplus
}
#endif


#endif /* Include Guard */
